using System;
using System.Data;
using System.Xml;
using System.Collections;
using System.Runtime.Serialization;
using System.ComponentModel;
using ACME.Northwind.Business.Rules;
using ACME.Northwind.Business.SelectCommands;
using ACME.Northwind.Domain.Objects;
using Widgetsphere.Core.DataAccess;
using Widgetsphere.Core.Util;
using Widgetsphere.Core.Logging;
using Widgetsphere.Core.Exceptions;
using ACME.Northwind.Business.LINQ;
using System.IO;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Data.Linq;
using System.Linq;
using System.Text;
using Widgetsphere.Core.EventArgs;
using System.Text.RegularExpressions;

namespace ACME.Northwind.Business.Objects
{
	 /// <summary>
	 /// The collection to hold 'Customer' entities
	 /// </summary>
	 [Serializable()]
	 public partial class CustomerCollection : BusinessCollectionPersistableBase, IPersistableBusinessCollection, IDisposable, IEnumerator, IEnumerable<Customer>, IWrappingClass
	 {
		#region Member Variables

		internal DomainCustomerCollection wrappedClass;

		/// <summary>
		/// The parent subdomain object
		/// </summary>
		protected SubDomain _subDomain = null;

		#endregion

		#region Constructor / Initialize

		internal CustomerCollection(DomainCustomerCollection classToWrap)
		{
			_subDomain = classToWrap.SubDomain;
			wrappedClass = classToWrap;
		}

		/// <summary>
		/// Constructor that enables you to specify a modifier
		/// </summary>
		/// <param name="modifier">Used in audit operations to track changes</param>
		public CustomerCollection(string modifier)
		{
			_subDomain = new SubDomain(modifier);
			ResetWrappedClass((DomainCustomerCollection)_subDomain.GetDomainCollection(Collections.CustomerCollection));
		}

		/// <summary>
		/// The default constructor
		/// </summary>
		public CustomerCollection() 
		{
			_subDomain = new SubDomain("");
			ResetWrappedClass((DomainCustomerCollection)_subDomain.GetDomainCollection(Collections.CustomerCollection));
		}

		#endregion

		#region Property Implementations

		/// <summary>
		/// Returns the internal object that this object wraps
		/// </summary>
		[System.ComponentModel.Browsable(false)]
		internal virtual object WrappedClass
		{
			get { return wrappedClass ; }
			set { wrappedClass = (DomainCustomerCollection)value ; }
		}

		//WrappingClass Interface
		object IWrappingClass.WrappedClass
		{
			get { return this.WrappedClass; }
			set { this.WrappedClass = value; }
		}

		/// <summary>
		/// Specifies a modifier string to be used in the audit functionality
		/// </summary>
		public string Modifier
		{
			get
			{
				try
				{
					return wrappedClass.Modifier;
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
		}

		/// <summary>
		/// A reference to the SubDomain that holds this collection
		/// </summary>
		public SubDomain SubDomain
		{
			get
			{
				try
				{
					return wrappedClass.SubDomain;
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
		}

		/// <summary>
		/// Returns the number of items in this collection
		/// </summary>
		public override int Count
		{
			get
			{
				try
				{
					lock (wrappedClass.SubDomain)
					{
						DataTable dt = wrappedClass.GetChanges(DataRowState.Deleted);
						if (dt == null) return wrappedClass.Count;
						else return wrappedClass.Count - dt.Rows.Count;
					}
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
		}

		/// <summary>
		/// Determines the type of object contained by this collection.
		/// </summary>
		public virtual Type ContainedType
		{
			get { return typeof(Customer); }
		}

		/// <summary>
		/// Determines the type of collection for this object.
		/// </summary>
		public virtual Collections Collection
		{
      get { return Collections.CustomerCollection; }
		}

		#endregion

		#region Enumerator

		/// <summary>
		/// Gets or sets the element at the specified index.
		/// </summary>
		/// <param name="index">The zero-based index of the element to get or set. </param>
		/// <returns>The element at the specified index.</returns>
		public virtual Customer this[int index]
		{
			get
			{
				try
				{
					IEnumerator internalEnumerator = this.GetEnumerator();
					internalEnumerator.Reset();
					int ii = -1;
					while(ii < index)
					{
						internalEnumerator.MoveNext();
						ii++;
					}
					Customer retval = (Customer)internalEnumerator.Current;
					if (retval.wrappedClass == null)
					{
						if (!((0 <= index) && (index < this.Count)))
							throw new IndexOutOfRangeException();
						else
							throw new Exception("The item is null. This is not a valid state.");
					}
					else return (Customer)internalEnumerator.Current;
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
		}

		#endregion

		#region Methods

		/// <summary>
		/// Create a new object to later add to this collection
		/// </summary>
		public virtual Customer NewItem(string CustomerId)
		{
			try
			{
				lock (wrappedClass.SubDomain)
				{
					return new Customer(wrappedClass.NewItem(CustomerId));
				}
			}
			catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
			catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
		}

		/// <summary>
		/// Create a new object to later add to this collection
		/// </summary>
		public virtual Customer NewItem() 
		{
			try
			{
				lock (wrappedClass.SubDomain)
				{
					return new Customer(wrappedClass.NewItem());
				}
			}
			catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
			catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
		}

		/// <summary>
		/// Add a newly created entity to this collection.
		/// </summary>
		public virtual void AddItem(Customer item) 
		{
			try
			{
				lock (wrappedClass.SubDomain)
				{
					wrappedClass.AddItem((DomainCustomer)item.WrappedClass);
				}
			}
			catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
			catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
		}

		/// <summary>
		/// Takes an IVisitor object and iterates through each item in this collection
		/// </summary>
		/// <param name="visitor">The object that processes each collection item</param>
		public virtual void ProcessVisitor(IVisitor visitor)
		{
			if (visitor == null) throw new Exception("This object cannot be null.");
			lock(this)
			{
				foreach (IBusinessObject item in this)
				{
					visitor.Visit(item);
				}
			}
		}

		#region Static SQL Methods

		internal static string GetFieldAliasFromFieldNameSqlMapping(string alias)
		{
			alias = alias.Replace("[", "").Replace("]", "");
			switch (alias.ToLower())
			{
				case "region": return "region";
				case "postalcode": return "postalcode";
				case "phone": return "phone";
				case "fax": return "fax";
				case "customerid": return "customerid";
				case "country": return "country";
				case "contacttitle": return "contacttitle";
				case "contactname": return "contactname";
				case "companyname": return "companyname";
				case "city": return "city";
				case "address": return "address";
				case "created_date": return "createddate";
				case "created_by": return "createdby";
				case "modified_date": return "modifieddate";
				case "modified_by": return "modifiedby";
				default: throw new Exception("The select clause is not valid.");
			}
		}

		internal static string GetTableFromFieldAliasSqlMapping(string alias)
		{
			switch (alias.ToLower())
			{
				case "region": return "Customers";
				case "postalcode": return "Customers";
				case "phone": return "Customers";
				case "fax": return "Customers";
				case "customerid": return "Customers";
				case "country": return "Customers";
				case "contacttitle": return "Customers";
				case "contactname": return "Customers";
				case "companyname": return "Customers";
				case "city": return "Customers";
				case "address": return "Customers";
				case "createdby": return "Customers";
				case "createddate": return "Customers";
				case "modifiedby": return "Customers";
				case "modifieddate": return "Customers";
				case "timestamp": return "Customers";
				default: throw new Exception("The select clause is not valid.");
			}
		}

		internal static string GetTableFromFieldNameSqlMapping(string field)
		{
			switch (field.ToLower())
			{
				case "region": return "Customers";
				case "postalcode": return "Customers";
				case "phone": return "Customers";
				case "fax": return "Customers";
				case "customerid": return "Customers";
				case "country": return "Customers";
				case "contacttitle": return "Customers";
				case "contactname": return "Customers";
				case "companyname": return "Customers";
				case "city": return "Customers";
				case "address": return "Customers";
				case "created_by": return "Customers";
				case "created_date": return "Customers";
				case "modified_by": return "Customers";
				case "modified_date": return "Customers";
				case "time_stamp": return "Customers";
				default: throw new Exception("The select clause is not valid.");
			}
		}

		internal static string GetRemappedLinqSql(string sql, string parentAlias, LinqSQLFromClauseCollection childTables)
		{
			sql = Regex.Replace(sql, "\\[" + parentAlias + "\\]\\.\\[region\\]", "[" + childTables.GetBaseAliasTable(parentAlias, "Customers") + "].[region]", RegexOptions.IgnoreCase);
			sql = Regex.Replace(sql, "\\[" + parentAlias + "\\]\\.\\[postalcode\\]", "[" + childTables.GetBaseAliasTable(parentAlias, "Customers") + "].[postalcode]", RegexOptions.IgnoreCase);
			sql = Regex.Replace(sql, "\\[" + parentAlias + "\\]\\.\\[phone\\]", "[" + childTables.GetBaseAliasTable(parentAlias, "Customers") + "].[phone]", RegexOptions.IgnoreCase);
			sql = Regex.Replace(sql, "\\[" + parentAlias + "\\]\\.\\[fax\\]", "[" + childTables.GetBaseAliasTable(parentAlias, "Customers") + "].[fax]", RegexOptions.IgnoreCase);
			sql = Regex.Replace(sql, "\\[" + parentAlias + "\\]\\.\\[customerid\\]", "[" + childTables.GetBaseAliasTable(parentAlias, "Customers") + "].[customerid]", RegexOptions.IgnoreCase);
			sql = Regex.Replace(sql, "\\[" + parentAlias + "\\]\\.\\[country\\]", "[" + childTables.GetBaseAliasTable(parentAlias, "Customers") + "].[country]", RegexOptions.IgnoreCase);
			sql = Regex.Replace(sql, "\\[" + parentAlias + "\\]\\.\\[contacttitle\\]", "[" + childTables.GetBaseAliasTable(parentAlias, "Customers") + "].[contacttitle]", RegexOptions.IgnoreCase);
			sql = Regex.Replace(sql, "\\[" + parentAlias + "\\]\\.\\[contactname\\]", "[" + childTables.GetBaseAliasTable(parentAlias, "Customers") + "].[contactname]", RegexOptions.IgnoreCase);
			sql = Regex.Replace(sql, "\\[" + parentAlias + "\\]\\.\\[companyname\\]", "[" + childTables.GetBaseAliasTable(parentAlias, "Customers") + "].[companyname]", RegexOptions.IgnoreCase);
			sql = Regex.Replace(sql, "\\[" + parentAlias + "\\]\\.\\[city\\]", "[" + childTables.GetBaseAliasTable(parentAlias, "Customers") + "].[city]", RegexOptions.IgnoreCase);
			sql = Regex.Replace(sql, "\\[" + parentAlias + "\\]\\.\\[address\\]", "[" + childTables.GetBaseAliasTable(parentAlias, "Customers") + "].[address]", RegexOptions.IgnoreCase);
			sql = Regex.Replace(sql, "\\[" + parentAlias + "\\]\\.\\[createdby\\]", "[" + childTables.GetBaseAliasTable(parentAlias, "Customers") + "].[createdby]", RegexOptions.IgnoreCase);
			sql = Regex.Replace(sql, "\\[" + parentAlias + "\\]\\.\\[createddate\\]", "[" + childTables.GetBaseAliasTable(parentAlias, "Customers") + "].[createddate]", RegexOptions.IgnoreCase);
			sql = Regex.Replace(sql, "\\[" + parentAlias + "\\]\\.\\[modifiedby\\]", "[" + childTables.GetBaseAliasTable(parentAlias, "Customers") + "].[modifiedby]", RegexOptions.IgnoreCase);
			sql = Regex.Replace(sql, "\\[" + parentAlias + "\\]\\.\\[modifieddate\\]", "[" + childTables.GetBaseAliasTable(parentAlias, "Customers") + "].[modifieddate]", RegexOptions.IgnoreCase);
			sql = Regex.Replace(sql, "\\[" + parentAlias + "\\]\\.\\[timestamp\\]", "[" + childTables.GetBaseAliasTable(parentAlias, "Customers") + "].[timestamp]", RegexOptions.IgnoreCase);
			return sql;
		}

		internal static string GetPagedSQL(List<LinqSQLField> fieldList, LinqSQLFromClauseCollection fromLinkList, string whereClause, object paging, QueryOptimizer optimizer)
		{
			StringBuilder sb = new StringBuilder();
			CustomerPaging paging2 = (CustomerPaging)paging;

			//Calculate the SELECT clause
			sb.Append("SELECT ");
			int index = 0;
			foreach (LinqSQLField field in fieldList)
			{
				sb.Append("[t0].[" + field.Name + "]");
				if (index < fieldList.Count - 1) sb.Append(", ");
				index++;
			}
			sb.AppendLine();
			sb.AppendLine("FROM (");

			//Calculate the Inner SELECT clause
			sb.Append("SELECT ");
			index = 0;
			foreach (LinqSQLField field in fieldList)
			{
				sb.Append(field.GetSQL(false));
				if (index < fieldList.Count - 1) sb.Append(", ");
				index++;
			}
			sb.AppendLine();

			//If there is no sort then add primary key
			if (paging2.OrderByList.Count == 0)
			{
				paging2.OrderByList.Add(new CustomerPagingFieldItem(Customer.FieldNameConstants.CustomerId));
			}

			//Determine the paging sort
			bool isPrimary = false;
			string orderByClause = "";
			foreach (CustomerPagingFieldItem fieldItem in paging2.OrderByList)
			{
				if (orderByClause != "") orderByClause += ", ";
				switch (fieldItem.Field.ToString().ToLower())
				{
					case "region": orderByClause += "[" + (from x in fieldList where x.Alias.ToLower() == fieldItem.Field.ToString().ToLower() select x).FirstOrDefault().Table + "].[Region]" + (fieldItem.Ascending ? "" : " DESC"); break;
					case "postalcode": orderByClause += "[" + (from x in fieldList where x.Alias.ToLower() == fieldItem.Field.ToString().ToLower() select x).FirstOrDefault().Table + "].[PostalCode]" + (fieldItem.Ascending ? "" : " DESC"); break;
					case "phone": orderByClause += "[" + (from x in fieldList where x.Alias.ToLower() == fieldItem.Field.ToString().ToLower() select x).FirstOrDefault().Table + "].[Phone]" + (fieldItem.Ascending ? "" : " DESC"); break;
					case "fax": orderByClause += "[" + (from x in fieldList where x.Alias.ToLower() == fieldItem.Field.ToString().ToLower() select x).FirstOrDefault().Table + "].[Fax]" + (fieldItem.Ascending ? "" : " DESC"); break;
					case "customerid": orderByClause += "[" + (from x in fieldList where x.Alias.ToLower() == fieldItem.Field.ToString().ToLower() select x).FirstOrDefault().Table + "].[CustomerID]" + (fieldItem.Ascending ? "" : " DESC"); isPrimary = true;break;
					case "country": orderByClause += "[" + (from x in fieldList where x.Alias.ToLower() == fieldItem.Field.ToString().ToLower() select x).FirstOrDefault().Table + "].[Country]" + (fieldItem.Ascending ? "" : " DESC"); break;
					case "contacttitle": orderByClause += "[" + (from x in fieldList where x.Alias.ToLower() == fieldItem.Field.ToString().ToLower() select x).FirstOrDefault().Table + "].[ContactTitle]" + (fieldItem.Ascending ? "" : " DESC"); break;
					case "contactname": orderByClause += "[" + (from x in fieldList where x.Alias.ToLower() == fieldItem.Field.ToString().ToLower() select x).FirstOrDefault().Table + "].[ContactName]" + (fieldItem.Ascending ? "" : " DESC"); break;
					case "companyname": orderByClause += "[" + (from x in fieldList where x.Alias.ToLower() == fieldItem.Field.ToString().ToLower() select x).FirstOrDefault().Table + "].[CompanyName]" + (fieldItem.Ascending ? "" : " DESC"); break;
					case "city": orderByClause += "[" + (from x in fieldList where x.Alias.ToLower() == fieldItem.Field.ToString().ToLower() select x).FirstOrDefault().Table + "].[City]" + (fieldItem.Ascending ? "" : " DESC"); break;
					case "address": orderByClause += "[" + (from x in fieldList where x.Alias.ToLower() == fieldItem.Field.ToString().ToLower() select x).FirstOrDefault().Table + "].[Address]" + (fieldItem.Ascending ? "" : " DESC"); break;
					case "createddate": orderByClause += "[t0].[created_date]" + (fieldItem.Ascending ? "" : " DESC"); break;
					case "createdby": orderByClause += "[t0].[created_by]" + (fieldItem.Ascending ? "" : " DESC"); break;
					case "modifieddate": orderByClause += "[t0].[modified_date]" + (fieldItem.Ascending ? "" : " DESC"); break;
					case "modifiedby": orderByClause += "[t0].[modified_by]" + (fieldItem.Ascending ? "" : " DESC"); break;
					default: throw new Exception("The order by clause is not valid.");
				}
			}

			//Get the primary key for predictable sorts
			string primarySortKey = "";
			primarySortKey = "[t0].[CustomerID]";

			sb.AppendLine(", ROW_NUMBER() OVER (ORDER BY " + orderByClause + ((primarySortKey == "") || ((isPrimary && (primarySortKey != ""))) ? "" : ", " + primarySortKey) + ") AS Row");
			//Calculate the FROM clause
			index = 0;
			sb.Append("FROM ");
			foreach (LinqSQLFromClause fromClause in fromLinkList)
			{
				sb.Append("[" + fromClause.TableName + "] AS [" + fromClause.Alias + "] ");
				if (optimizer.NoLocking) sb.Append("WITH (NOLOCK)");
				if (fromClause.LinkClause != "") sb.Append(fromClause.LinkClause + " ");

				if (index < fromLinkList.Count - 1)
				{
					sb.AppendLine();
					sb.Append("LEFT OUTER JOIN ");
				}

				index++;
			}
			sb.AppendLine();

			//Calculate the WHERE clause
			if (whereClause != "")
			{
				foreach (LinqSQLFromClause fromClause in fromLinkList)
				{
					//Only process table that were original and not inserted above
					if (fromClause.AnchorAlias == "")
					{
						whereClause = LinqSQLParser.GetRemappedLinqSql(fromClause, whereClause, fromLinkList);
					}
				}
				sb.Append("WHERE " + whereClause);
			}

			sb.AppendLine(") AS [t0]");
			sb.AppendLine("WHERE (Row >= " + (((paging2.PageIndex - 1) * paging2.RecordsperPage) + 1) + ") AND (Row <= " + (paging2.PageIndex * paging2.RecordsperPage) + ")");

			return sb.ToString();
		}

		#endregion

		/// <summary>
		/// Persists this collection to store.
		/// </summary>
		public override void Persist()
		{
			try
			{
				foreach (Customer item in this)
				{
					if (item.wrappedClass.RowState != DataRowState.Unchanged)
						item.OnValidate(new BusinessObjectEventArgs(item));
				}

				lock (wrappedClass.SubDomain)
				{
					wrappedClass.Persist();
				}
			}
			catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
			catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
		}

		/// <summary>
		/// Select all objects from store.
		/// </summary>
		public static CustomerCollection RunSelect()
		{
			return RunSelect("");
		}

		/// <summary>
		/// Select all objects from store.
		/// </summary>
		public static CustomerCollection RunSelect(string modifier)
		{
			try
			{
				CustomerCollection returnVal = new CustomerCollection(DomainCustomerCollection.RunSelect(modifier));
				return returnVal;
			}
			catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
			catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
		}

		/// <summary>
		/// Using the specified Where expression, execute a query against the database to return a result set
		/// </summary>
		/// <param name="where">The expression that determines the records selected</param>
		public static CustomerCollection RunSelect(Expression<Func<CustomerQuery, bool>> where)
		{
			return RunSelect(where, "");
		}

		/// <summary>
		/// Using the specified Where expression, execute a query against the database to return a result set
		/// </summary>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="modifier">The modified audit trail</param>
		public static CustomerCollection RunSelect(Expression<Func<CustomerQuery, bool>> where, string modifier)
		{
			return RunSelect(where, new QueryOptimizer(), modifier);
		}

		/// <summary>
		/// Using the specified Where expression, execute a query against the database to return a result set
		/// </summary>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		/// <param name="modifier">The modified audit trail</param>
		public static CustomerCollection RunSelect(Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer, string modifier)
		{
			SubDomain subDomain = new SubDomain(modifier);
			DataContext dc = new DataContext(ConfigurationValues.GetInstance().ConnectionString);
			Table<CustomerQuery> template = dc.GetTable<CustomerQuery>();
			var cmd = BusinessCollectionPersistableBase.GetCommand<CustomerQuery>(dc, template, where);
			cmd.CommandTimeout = ConfigurationValues.GetInstance().DefaultTimeOut;
			LinqSQLParser parser = LinqSQLParser.Create(cmd.CommandText);
			cmd.CommandText = parser.GetSQL(optimizer);
			dc.Connection.Open();
			DateTime startTime = DateTime.Now;
			var result = dc.Translate<CustomerQuery>(cmd.ExecuteReader());
			DateTime endTime = DateTime.Now;
			optimizer.TotalMilliseconds = (long)endTime.Subtract(startTime).TotalMilliseconds;
			CustomerCollection retval = subDomain.GetCollection<CustomerCollection>();
			foreach (CustomerQuery item in result)
			{
				if (retval.GetItemByPK(item.CustomerId) == null)
				{
					Customer newItem = retval.NewItem(item.CustomerId);
					LoadDataRow(item, newItem);
					retval.AddItem(newItem);
				}
			}
			retval.wrappedClass.AcceptChanges();
			retval.wrappedClass.EndLoadData();
			dc.Connection.Close();
			return retval;
		}

		/// <summary>
		/// Using the specified Where expression, execute a query against the database to return a result set
		/// </summary>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="paging">The paging object to determine how the results are paged.</param>
		public static CustomerCollection RunSelect(Expression<Func<CustomerQuery, bool>> where, CustomerPaging paging)
		{
			return RunSelect(where, paging, "");
		}

		/// <summary>
		/// Using the specified Where expression, execute a query against the database to return a result set
		/// </summary>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="paging">The paging object to determine how the results are paged.</param>
		/// <param name="modifier">The modified audit trail</param>
		public static CustomerCollection RunSelect(Expression<Func<CustomerQuery, bool>> where, CustomerPaging paging, string modifier)
		{
			return RunSelect(where, paging, new QueryOptimizer(), modifier);
		}

		/// <summary>
		/// Using the specified Where expression, execute a query against the database to return a result set
		/// </summary>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="paging">The paging object to determine how the results are paged.</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		/// <param name="modifier">The modified audit trail</param>
		public static CustomerCollection RunSelect(Expression<Func<CustomerQuery, bool>> where, CustomerPaging paging, QueryOptimizer optimizer, string modifier)
		{
			if (paging == null) throw new Exception("The paging object cannot be null.");
			SubDomain subDomain = new SubDomain(modifier);

			DataContext dc = new DataContext(ConfigurationValues.GetInstance().ConnectionString);
			Table<CustomerQuery> template = dc.GetTable<CustomerQuery>();
			var cmd = BusinessCollectionPersistableBase.GetCommand<CustomerQuery>(dc, template, where);
			cmd.CommandTimeout = ConfigurationValues.GetInstance().DefaultTimeOut;
			LinqSQLParser parser = LinqSQLParser.Create(cmd.CommandText, paging);
			cmd.CommandText = parser.GetSQL(optimizer);
			dc.Connection.Open();
			DateTime startTime = DateTime.Now;
			var result = dc.Translate<CustomerQuery>(cmd.ExecuteReader());
			DateTime endTime = DateTime.Now;
			optimizer.TotalMilliseconds = (long)endTime.Subtract(startTime).TotalMilliseconds;
			CustomerCollection retval = subDomain.GetCollection<CustomerCollection>();
			foreach (CustomerQuery item in result)
			{
				if (retval.GetItemByPK(item.CustomerId) == null)
				{
					Customer newItem = retval.NewItem(item.CustomerId);
					LoadDataRow(item, newItem);
					retval.AddItem(newItem);
				}
			}
			retval.wrappedClass.AcceptChanges();
			retval.wrappedClass.EndLoadData();
			dc.Connection.Close();
			paging.RecordCount = GetCount(where);
			return retval;
		}

		private static void LoadDataRow(CustomerQuery item, Customer newItem)
		{
			newItem.wrappedClass["Region"] = StringHelper.ConvertToDatabase(item.Region);
			newItem.wrappedClass["PostalCode"] = StringHelper.ConvertToDatabase(item.PostalCode);
			newItem.wrappedClass["Phone"] = StringHelper.ConvertToDatabase(item.Phone);
			newItem.wrappedClass["Fax"] = StringHelper.ConvertToDatabase(item.Fax);
			newItem.wrappedClass["CustomerID"] = item.CustomerId;
			newItem.wrappedClass["Country"] = StringHelper.ConvertToDatabase(item.Country);
			newItem.wrappedClass["ContactTitle"] = StringHelper.ConvertToDatabase(item.ContactTitle);
			newItem.wrappedClass["ContactName"] = StringHelper.ConvertToDatabase(item.ContactName);
			newItem.wrappedClass["CompanyName"] = item.CompanyName;
			newItem.wrappedClass["City"] = StringHelper.ConvertToDatabase(item.City);
			newItem.wrappedClass["Address"] = StringHelper.ConvertToDatabase(item.Address);
			newItem.wrappedClass["CreatedDate"] = StringHelper.ConvertToDatabase(item.CreatedDate);
			newItem.wrappedClass["CreatedBy"] = StringHelper.ConvertToDatabase(item.CreatedBy);
			newItem.wrappedClass["ModifiedDate"] = StringHelper.ConvertToDatabase(item.ModifiedDate);
			newItem.wrappedClass["ModifiedBy"] = StringHelper.ConvertToDatabase(item.ModifiedBy);
			newItem.wrappedClass["TimeStamp"] = item.TimeStamp;
		}


		/// <summary>
		/// Select a set of objects from the database with custom search object.
		/// </summary>
		/// <param name="search">The search object to use for searching.</param>
		/// <param name="modifier">The identifier used for the create and modify audits.</param>
		public static CustomerCollection RunSelect(CustomerSearch search, string modifier)
		{
			if (search == null) throw new Exception("The 'Search' object cannot be null!");
			try
			{
				CustomerCollection returnVal = new CustomerCollection(DomainCustomerCollection.RunSelect(search, modifier));
				return returnVal;
			}
			catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
			catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
		}

		/// <summary>
		/// Select a paged set of objects from the database with custom search object.
		/// </summary>
		/// <param name="search">The search object to use for searching.</param>
		/// <param name="paging">The paging object to determine how the results are paged.</param>
		/// <param name="modifier">The identifier used for the create and modify audits.</param>
		public static CustomerCollection RunSelect(CustomerSearch search, CustomerPaging paging, string modifier)
		{
			if (search == null) throw new Exception("The 'Search' object cannot be null!");
			try
			{
				CustomerCollection returnVal = new CustomerCollection(DomainCustomerCollection.RunSelect(search, paging, modifier));
				return returnVal;
			}
			catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
			catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
		}

		/// <summary>
		/// Get the maximum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static int? GetMax(Expression<Func<CustomerQuery, int>> select)
		{
			return GetMax(select, x => true);
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static int? GetMax(Expression<Func<CustomerQuery, int>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMax(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static int? GetMax(Expression<Func<CustomerQuery, int>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, int>.GetMax(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the maximum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static int? GetMax(Expression<Func<CustomerQuery, int?>> select)
		{
			return GetMax(select, x => true);
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static int? GetMax(Expression<Func<CustomerQuery, int?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMax(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static int? GetMax(Expression<Func<CustomerQuery, int?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, int?>.GetMax(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the maximum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static Single? GetMax(Expression<Func<CustomerQuery, Single>> select)
		{
			return GetMax(select, x => true);
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static Single? GetMax(Expression<Func<CustomerQuery, Single>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMax(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static Single? GetMax(Expression<Func<CustomerQuery, Single>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, Single>.GetMax(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the maximum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static Single? GetMax(Expression<Func<CustomerQuery, Single?>> select)
		{
			return GetMax(select, x => true);
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static Single? GetMax(Expression<Func<CustomerQuery, Single?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMax(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static Single? GetMax(Expression<Func<CustomerQuery, Single?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, Single?>.GetMax(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the maximum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetMax(Expression<Func<CustomerQuery, double>> select)
		{
			return GetMax(select, x => true);
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetMax(Expression<Func<CustomerQuery, double>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMax(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetMax(Expression<Func<CustomerQuery, double>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, double>.GetMax(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the maximum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetMax(Expression<Func<CustomerQuery, double?>> select)
		{
			return GetMax(select, x => true);
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetMax(Expression<Func<CustomerQuery, double?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMax(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetMax(Expression<Func<CustomerQuery, double?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, double?>.GetMax(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the maximum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static decimal? GetMax(Expression<Func<CustomerQuery, decimal>> select)
		{
			return GetMax(select, x => true);
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static decimal? GetMax(Expression<Func<CustomerQuery, decimal>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMax(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static decimal? GetMax(Expression<Func<CustomerQuery, decimal>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, decimal>.GetMax(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the maximum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static decimal? GetMax(Expression<Func<CustomerQuery, decimal?>> select)
		{
			return GetMax(select, x => true);
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static decimal? GetMax(Expression<Func<CustomerQuery, decimal?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMax(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static decimal? GetMax(Expression<Func<CustomerQuery, decimal?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, decimal?>.GetMax(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the maximum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static string GetMax(Expression<Func<CustomerQuery, string>> select)
		{
			return GetMax(select, x => true);
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static string GetMax(Expression<Func<CustomerQuery, string>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMax(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static string GetMax(Expression<Func<CustomerQuery, string>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, string>.GetMax(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the maximum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static DateTime? GetMax(Expression<Func<CustomerQuery, DateTime>> select)
		{
			return GetMax(select, x => true);
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static DateTime? GetMax(Expression<Func<CustomerQuery, DateTime>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMax(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static DateTime? GetMax(Expression<Func<CustomerQuery, DateTime>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, DateTime>.GetMax(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the maximum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static DateTime? GetMax(Expression<Func<CustomerQuery, DateTime?>> select)
		{
			return GetMax(select, x => true);
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static DateTime? GetMax(Expression<Func<CustomerQuery, DateTime?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMax(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the maximum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static DateTime? GetMax(Expression<Func<CustomerQuery, DateTime?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, DateTime?>.GetMax(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the minimum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static int? GetMin(Expression<Func<CustomerQuery, int>> select)
		{
			return GetMin(select, x => true);
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static int? GetMin(Expression<Func<CustomerQuery, int>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMin(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static int? GetMin(Expression<Func<CustomerQuery, int>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, int>.GetMin(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the minimum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static int? GetMin(Expression<Func<CustomerQuery, int?>> select)
		{
			return GetMin(select, x => true);
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static int? GetMin(Expression<Func<CustomerQuery, int?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMin(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static int? GetMin(Expression<Func<CustomerQuery, int?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, int?>.GetMin(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the minimum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static Single? GetMin(Expression<Func<CustomerQuery, Single>> select)
		{
			return GetMin(select, x => true);
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static Single? GetMin(Expression<Func<CustomerQuery, Single>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMin(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static Single? GetMin(Expression<Func<CustomerQuery, Single>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, Single>.GetMin(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the minimum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static Single? GetMin(Expression<Func<CustomerQuery, Single?>> select)
		{
			return GetMin(select, x => true);
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static Single? GetMin(Expression<Func<CustomerQuery, Single?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMin(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static Single? GetMin(Expression<Func<CustomerQuery, Single?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, Single?>.GetMin(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the minimum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetMin(Expression<Func<CustomerQuery, double>> select)
		{
			return GetMin(select, x => true);
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetMin(Expression<Func<CustomerQuery, double>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMin(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetMin(Expression<Func<CustomerQuery, double>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, double>.GetMin(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the minimum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetMin(Expression<Func<CustomerQuery, double?>> select)
		{
			return GetMin(select, x => true);
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetMin(Expression<Func<CustomerQuery, double?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMin(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetMin(Expression<Func<CustomerQuery, double?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, double?>.GetMin(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the minimum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static decimal? GetMin(Expression<Func<CustomerQuery, decimal>> select)
		{
			return GetMin(select, x => true);
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static decimal? GetMin(Expression<Func<CustomerQuery, decimal>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMin(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static decimal? GetMin(Expression<Func<CustomerQuery, decimal>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, decimal>.GetMin(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the minimum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static decimal? GetMin(Expression<Func<CustomerQuery, decimal?>> select)
		{
			return GetMin(select, x => true);
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static decimal? GetMin(Expression<Func<CustomerQuery, decimal?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMin(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static decimal? GetMin(Expression<Func<CustomerQuery, decimal?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, decimal?>.GetMin(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the minimum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static string GetMin(Expression<Func<CustomerQuery, string>> select)
		{
			return GetMin(select, x => true);
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static string GetMin(Expression<Func<CustomerQuery, string>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMin(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static string GetMin(Expression<Func<CustomerQuery, string>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, string>.GetMin(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the minimum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static DateTime? GetMin(Expression<Func<CustomerQuery, DateTime>> select)
		{
			return GetMin(select, x => true);
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static DateTime? GetMin(Expression<Func<CustomerQuery, DateTime>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMin(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static DateTime? GetMin(Expression<Func<CustomerQuery, DateTime>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, DateTime>.GetMin(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the minimum value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static DateTime? GetMin(Expression<Func<CustomerQuery, DateTime?>> select)
		{
			return GetMin(select, x => true);
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static DateTime? GetMin(Expression<Func<CustomerQuery, DateTime?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetMin(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the minimum value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static DateTime? GetMin(Expression<Func<CustomerQuery, DateTime?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, DateTime?>.GetMin(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the average value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, int>> select)
		{
			return GetAverage(select, x => true);
		}

		/// <summary>
		/// Get the average value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, int>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetAverage(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the average value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, int>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, int>.GetAverage(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the average value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, int?>> select)
		{
			return GetAverage(select, x => true);
		}

		/// <summary>
		/// Get the average value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, int?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetAverage(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the average value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, int?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, int?>.GetAverage(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the average value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, Single>> select)
		{
			return GetAverage(select, x => true);
		}

		/// <summary>
		/// Get the average value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, Single>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetAverage(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the average value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, Single>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, Single>.GetAverage(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the average value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, Single?>> select)
		{
			return GetAverage(select, x => true);
		}

		/// <summary>
		/// Get the average value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, Single?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetAverage(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the average value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, Single?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, Single?>.GetAverage(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the average value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, double>> select)
		{
			return GetAverage(select, x => true);
		}

		/// <summary>
		/// Get the average value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, double>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetAverage(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the average value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, double>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, double>.GetAverage(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the average value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, double?>> select)
		{
			return GetAverage(select, x => true);
		}

		/// <summary>
		/// Get the average value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, double?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetAverage(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the average value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetAverage(Expression<Func<CustomerQuery, double?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, double?>.GetAverage(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the average value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static decimal? GetAverage(Expression<Func<CustomerQuery, decimal>> select)
		{
			return GetAverage(select, x => true);
		}

		/// <summary>
		/// Get the average value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static decimal? GetAverage(Expression<Func<CustomerQuery, decimal>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetAverage(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the average value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static decimal? GetAverage(Expression<Func<CustomerQuery, decimal>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, decimal>.GetAverage(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the average value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static decimal? GetAverage(Expression<Func<CustomerQuery, decimal?>> select)
		{
			return GetAverage(select, x => true);
		}

		/// <summary>
		/// Get the average value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static decimal? GetAverage(Expression<Func<CustomerQuery, decimal?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetAverage(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the average value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static decimal? GetAverage(Expression<Func<CustomerQuery, decimal?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, decimal?>.GetAverage(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the summary value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetSum(Expression<Func<CustomerQuery, int>> select)
		{
			return GetSum(select, x => true);
		}

		/// <summary>
		/// Get the summary value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetSum(Expression<Func<CustomerQuery, int>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetSum(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the summary value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetSum(Expression<Func<CustomerQuery, int>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, int>.GetSum(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the summary value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetSum(Expression<Func<CustomerQuery, int?>> select)
		{
			return GetSum(select, x => true);
		}

		/// <summary>
		/// Get the summary value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetSum(Expression<Func<CustomerQuery, int?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetSum(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the summary value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetSum(Expression<Func<CustomerQuery, int?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, int?>.GetSum(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the summary value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetSum(Expression<Func<CustomerQuery, Single>> select)
		{
			return GetSum(select, x => true);
		}

		/// <summary>
		/// Get the summary value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetSum(Expression<Func<CustomerQuery, Single>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetSum(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the summary value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetSum(Expression<Func<CustomerQuery, Single>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, Single>.GetSum(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the summary value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetSum(Expression<Func<CustomerQuery, Single?>> select)
		{
			return GetSum(select, x => true);
		}

		/// <summary>
		/// Get the summary value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetSum(Expression<Func<CustomerQuery, Single?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetSum(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the summary value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetSum(Expression<Func<CustomerQuery, Single?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, Single?>.GetSum(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the summary value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetSum(Expression<Func<CustomerQuery, double>> select)
		{
			return GetSum(select, x => true);
		}

		/// <summary>
		/// Get the summary value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetSum(Expression<Func<CustomerQuery, double>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetSum(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the summary value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetSum(Expression<Func<CustomerQuery, double>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, double>.GetSum(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the summary value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetSum(Expression<Func<CustomerQuery, double?>> select)
		{
			return GetSum(select, x => true);
		}

		/// <summary>
		/// Get the summary value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetSum(Expression<Func<CustomerQuery, double?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetSum(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the summary value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetSum(Expression<Func<CustomerQuery, double?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, double?>.GetSum(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the summary value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetSum(Expression<Func<CustomerQuery, decimal>> select)
		{
			return GetSum(select, x => true);
		}

		/// <summary>
		/// Get the summary value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetSum(Expression<Func<CustomerQuery, decimal>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetSum(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the summary value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetSum(Expression<Func<CustomerQuery, decimal>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, decimal>.GetSum(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the summary value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static double? GetSum(Expression<Func<CustomerQuery, decimal?>> select)
		{
			return GetSum(select, x => true);
		}

		/// <summary>
		/// Get the summary value of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static double? GetSum(Expression<Func<CustomerQuery, decimal?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetSum(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the summary value of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static double? GetSum(Expression<Func<CustomerQuery, decimal?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, decimal?>.GetSum(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get the count of all objects
		/// </summary>
		public static int GetCount()
		{
			return GetCount(x => true, new QueryOptimizer());
		}

		/// <summary>
		/// Get the count of all objects
		/// </summary>
		public static int GetCount(QueryOptimizer optimizer)
		{
			return GetCount(x => true, optimizer);
		}

		/// <summary>
		/// Get the count of objects that match the Where condition
		/// </summary>
		/// <param name="where">The expression that determines the records selected</param>
		public static int GetCount(Expression<Func<CustomerQuery, bool>> where)
		{
			return GetCount(where, new QueryOptimizer());
		}

		/// <summary>
		/// Get the count of objects that match the Where condition
		/// </summary>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static int GetCount(Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, int>.GetCount(where, optimizer);
		}

		/// <summary>
		/// Get a list of distinct values of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static IEnumerable<int> GetDistinct(Expression<Func<CustomerQuery, int>> select)
		{
			return GetDistinct(select, x => true);
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static IEnumerable<int> GetDistinct(Expression<Func<CustomerQuery, int>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetDistinct(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static IEnumerable<int> GetDistinct(Expression<Func<CustomerQuery, int>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, int>.GetDistinct(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get a list of distinct values of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static IEnumerable<int?> GetDistinct(Expression<Func<CustomerQuery, int?>> select)
		{
			return GetDistinct(select, x => true);
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static IEnumerable<int?> GetDistinct(Expression<Func<CustomerQuery, int?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetDistinct(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static IEnumerable<int?> GetDistinct(Expression<Func<CustomerQuery, int?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, int?>.GetDistinct(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get a list of distinct values of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static IEnumerable<Single> GetDistinct(Expression<Func<CustomerQuery, Single>> select)
		{
			return GetDistinct(select, x => true);
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static IEnumerable<Single> GetDistinct(Expression<Func<CustomerQuery, Single>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetDistinct(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static IEnumerable<Single> GetDistinct(Expression<Func<CustomerQuery, Single>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, Single>.GetDistinct(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get a list of distinct values of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static IEnumerable<Single?> GetDistinct(Expression<Func<CustomerQuery, Single?>> select)
		{
			return GetDistinct(select, x => true);
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static IEnumerable<Single?> GetDistinct(Expression<Func<CustomerQuery, Single?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetDistinct(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static IEnumerable<Single?> GetDistinct(Expression<Func<CustomerQuery, Single?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, Single?>.GetDistinct(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get a list of distinct values of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static IEnumerable<double> GetDistinct(Expression<Func<CustomerQuery, double>> select)
		{
			return GetDistinct(select, x => true);
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static IEnumerable<double> GetDistinct(Expression<Func<CustomerQuery, double>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetDistinct(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static IEnumerable<double> GetDistinct(Expression<Func<CustomerQuery, double>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, double>.GetDistinct(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get a list of distinct values of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static IEnumerable<double?> GetDistinct(Expression<Func<CustomerQuery, double?>> select)
		{
			return GetDistinct(select, x => true);
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static IEnumerable<double?> GetDistinct(Expression<Func<CustomerQuery, double?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetDistinct(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static IEnumerable<double?> GetDistinct(Expression<Func<CustomerQuery, double?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, double?>.GetDistinct(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get a list of distinct values of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static IEnumerable<decimal> GetDistinct(Expression<Func<CustomerQuery, decimal>> select)
		{
			return GetDistinct(select, x => true);
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static IEnumerable<decimal> GetDistinct(Expression<Func<CustomerQuery, decimal>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetDistinct(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static IEnumerable<decimal> GetDistinct(Expression<Func<CustomerQuery, decimal>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, decimal>.GetDistinct(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get a list of distinct values of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static IEnumerable<decimal?> GetDistinct(Expression<Func<CustomerQuery, decimal?>> select)
		{
			return GetDistinct(select, x => true);
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static IEnumerable<decimal?> GetDistinct(Expression<Func<CustomerQuery, decimal?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetDistinct(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static IEnumerable<decimal?> GetDistinct(Expression<Func<CustomerQuery, decimal?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, decimal?>.GetDistinct(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get a list of distinct values of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static IEnumerable<string> GetDistinct(Expression<Func<CustomerQuery, string>> select)
		{
			return GetDistinct(select, x => true);
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static IEnumerable<string> GetDistinct(Expression<Func<CustomerQuery, string>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetDistinct(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static IEnumerable<string> GetDistinct(Expression<Func<CustomerQuery, string>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, string>.GetDistinct(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get a list of distinct values of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static IEnumerable<DateTime> GetDistinct(Expression<Func<CustomerQuery, DateTime>> select)
		{
			return GetDistinct(select, x => true);
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static IEnumerable<DateTime> GetDistinct(Expression<Func<CustomerQuery, DateTime>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetDistinct(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static IEnumerable<DateTime> GetDistinct(Expression<Func<CustomerQuery, DateTime>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, DateTime>.GetDistinct(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get a list of distinct values of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static IEnumerable<DateTime?> GetDistinct(Expression<Func<CustomerQuery, DateTime?>> select)
		{
			return GetDistinct(select, x => true);
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static IEnumerable<DateTime?> GetDistinct(Expression<Func<CustomerQuery, DateTime?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetDistinct(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static IEnumerable<DateTime?> GetDistinct(Expression<Func<CustomerQuery, DateTime?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, DateTime?>.GetDistinct(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get a list of distinct values of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static IEnumerable<Guid> GetDistinct(Expression<Func<CustomerQuery, Guid>> select)
		{
			return GetDistinct(select, x => true);
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static IEnumerable<Guid> GetDistinct(Expression<Func<CustomerQuery, Guid>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetDistinct(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static IEnumerable<Guid> GetDistinct(Expression<Func<CustomerQuery, Guid>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, Guid>.GetDistinct(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Get a list of distinct values of the field for all objects
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		public static IEnumerable<Guid?> GetDistinct(Expression<Func<CustomerQuery, Guid?>> select)
		{
			return GetDistinct(select, x => true);
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		public static IEnumerable<Guid?> GetDistinct(Expression<Func<CustomerQuery, Guid?>> select, Expression<Func<CustomerQuery, bool>> where)
		{
			return GetDistinct(select, where, new QueryOptimizer());
		}

		/// <summary>
		/// Get a list of distinct values of the field in the set of records that match the Where condition
		/// </summary>
		/// <param name="select">The field to aggregate</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		public static IEnumerable<Guid?> GetDistinct(Expression<Func<CustomerQuery, Guid?>> select, Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, Guid?>.GetDistinct(select, where, optimizer, "Customers", GetDatabaseFieldName);
		}

		/// <summary>
		/// Update the specified field that matches the Where expression with the new data value
		/// </summary>
		/// <param name="select">The field to update</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="newValue">The new value to set the specified field in all matching records</param>
		/// <returns>The number of records affected</returns>
		public static int UpdateData(Expression<Func<CustomerQuery, int>> select, Expression<Func<CustomerQuery, bool>> where, int newValue)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, int>.UpdateData(select, where, newValue, "Customers", GetDatabaseFieldName, true);
		}

		/// <summary>
		/// Update the specified field that matches the Where expression with the new data value
		/// </summary>
		/// <param name="select">The field to update</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="newValue">The new value to set the specified field in all matching records</param>
		/// <returns>The number of records affected</returns>
		public static int UpdateData(Expression<Func<CustomerQuery, int?>> select, Expression<Func<CustomerQuery, bool>> where, int? newValue)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, int?>.UpdateData(select, where, newValue, "Customers", GetDatabaseFieldName, true);
		}

		/// <summary>
		/// Update the specified field that matches the Where expression with the new data value
		/// </summary>
		/// <param name="select">The field to update</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="newValue">The new value to set the specified field in all matching records</param>
		/// <returns>The number of records affected</returns>
		public static int UpdateData(Expression<Func<CustomerQuery, Single>> select, Expression<Func<CustomerQuery, bool>> where, Single newValue)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, Single>.UpdateData(select, where, newValue, "Customers", GetDatabaseFieldName, true);
		}

		/// <summary>
		/// Update the specified field that matches the Where expression with the new data value
		/// </summary>
		/// <param name="select">The field to update</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="newValue">The new value to set the specified field in all matching records</param>
		/// <returns>The number of records affected</returns>
		public static int UpdateData(Expression<Func<CustomerQuery, Single?>> select, Expression<Func<CustomerQuery, bool>> where, Single? newValue)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, Single?>.UpdateData(select, where, newValue, "Customers", GetDatabaseFieldName, true);
		}

		/// <summary>
		/// Update the specified field that matches the Where expression with the new data value
		/// </summary>
		/// <param name="select">The field to update</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="newValue">The new value to set the specified field in all matching records</param>
		/// <returns>The number of records affected</returns>
		public static int UpdateData(Expression<Func<CustomerQuery, decimal>> select, Expression<Func<CustomerQuery, bool>> where, decimal newValue)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, decimal>.UpdateData(select, where, newValue, "Customers", GetDatabaseFieldName, true);
		}

		/// <summary>
		/// Update the specified field that matches the Where expression with the new data value
		/// </summary>
		/// <param name="select">The field to update</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="newValue">The new value to set the specified field in all matching records</param>
		/// <returns>The number of records affected</returns>
		public static int UpdateData(Expression<Func<CustomerQuery, decimal?>> select, Expression<Func<CustomerQuery, bool>> where, decimal? newValue)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, decimal?>.UpdateData(select, where, newValue, "Customers", GetDatabaseFieldName, true);
		}

		/// <summary>
		/// Update the specified field that matches the Where expression with the new data value
		/// </summary>
		/// <param name="select">The field to update</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="newValue">The new value to set the specified field in all matching records</param>
		/// <returns>The number of records affected</returns>
		public static int UpdateData(Expression<Func<CustomerQuery, double>> select, Expression<Func<CustomerQuery, bool>> where, double newValue)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, double>.UpdateData(select, where, newValue, "Customers", GetDatabaseFieldName, true);
		}

		/// <summary>
		/// Update the specified field that matches the Where expression with the new data value
		/// </summary>
		/// <param name="select">The field to update</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="newValue">The new value to set the specified field in all matching records</param>
		/// <returns>The number of records affected</returns>
		public static int UpdateData(Expression<Func<CustomerQuery, double?>> select, Expression<Func<CustomerQuery, bool>> where, double? newValue)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, double?>.UpdateData(select, where, newValue, "Customers", GetDatabaseFieldName, true);
		}

		/// <summary>
		/// Update the specified field that matches the Where expression with the new data value
		/// </summary>
		/// <param name="select">The field to update</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="newValue">The new value to set the specified field in all matching records</param>
		/// <returns>The number of records affected</returns>
		public static int UpdateData(Expression<Func<CustomerQuery, string>> select, Expression<Func<CustomerQuery, bool>> where, string newValue)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, string>.UpdateData(select, where, newValue, "Customers", GetDatabaseFieldName, true);
		}

		/// <summary>
		/// Update the specified field that matches the Where expression with the new data value
		/// </summary>
		/// <param name="select">The field to update</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="newValue">The new value to set the specified field in all matching records</param>
		/// <returns>The number of records affected</returns>
		public static int UpdateData(Expression<Func<CustomerQuery, DateTime>> select, Expression<Func<CustomerQuery, bool>> where, DateTime newValue)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, DateTime>.UpdateData(select, where, newValue, "Customers", GetDatabaseFieldName, true);
		}

		/// <summary>
		/// Update the specified field that matches the Where expression with the new data value
		/// </summary>
		/// <param name="select">The field to update</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="newValue">The new value to set the specified field in all matching records</param>
		/// <returns>The number of records affected</returns>
		public static int UpdateData(Expression<Func<CustomerQuery, DateTime?>> select, Expression<Func<CustomerQuery, bool>> where, DateTime? newValue)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, DateTime?>.UpdateData(select, where, newValue, "Customers", GetDatabaseFieldName, true);
		}

		/// <summary>
		/// Update the specified field that matches the Where expression with the new data value
		/// </summary>
		/// <param name="select">The field to update</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="newValue">The new value to set the specified field in all matching records</param>
		/// <returns>The number of records affected</returns>
		public static int UpdateData(Expression<Func<CustomerQuery, bool>> select, Expression<Func<CustomerQuery, bool>> where, bool newValue)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, bool>.UpdateData(select, where, newValue, "Customers", GetDatabaseFieldName, true);
		}

		/// <summary>
		/// Update the specified field that matches the Where expression with the new data value
		/// </summary>
		/// <param name="select">The field to update</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="newValue">The new value to set the specified field in all matching records</param>
		/// <returns>The number of records affected</returns>
		public static int UpdateData(Expression<Func<CustomerQuery, bool?>> select, Expression<Func<CustomerQuery, bool>> where, bool? newValue)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, bool?>.UpdateData(select, where, newValue, "Customers", GetDatabaseFieldName, true);
		}

		/// <summary>
		/// Update the specified field that matches the Where expression with the new data value
		/// </summary>
		/// <param name="select">The field to update</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="newValue">The new value to set the specified field in all matching records</param>
		/// <returns>The number of records affected</returns>
		public static int UpdateData(Expression<Func<CustomerQuery, Guid>> select, Expression<Func<CustomerQuery, bool>> where, Guid newValue)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, Guid>.UpdateData(select, where, newValue, "Customers", GetDatabaseFieldName, true);
		}

		/// <summary>
		/// Update the specified field that matches the Where expression with the new data value
		/// </summary>
		/// <param name="select">The field to update</param>
		/// <param name="where">The expression that determines the records selected</param>
		/// <param name="newValue">The new value to set the specified field in all matching records</param>
		/// <returns>The number of records affected</returns>
		public static int UpdateData(Expression<Func<CustomerQuery, Guid?>> select, Expression<Func<CustomerQuery, bool>> where, Guid? newValue)
		{
			return BusinessObjectQuery<Customer, CustomerQuery, Guid?>.UpdateData(select, where, newValue, "Customers", GetDatabaseFieldName, true);
		}

		/// <summary>
		/// Delete all records that match a where condition
		/// </summary>
		/// <param name="where">The expression that determines the records deleted</param>
		/// <returns>The number of rows deleted</returns>
		public static int DeleteData(Expression<Func<CustomerQuery, bool>> where)
		{
			return DeleteData(where, new QueryOptimizer());
		}

		/// <summary>
		/// Delete all records that match a where condition
		/// </summary>
		/// <param name="where">The expression that determines the records deleted</param>
		/// <param name="optimizer">The optimization object to use for running queries</param>
		/// <returns>The number of rows deleted</returns>
		public static int DeleteData(Expression<Func<CustomerQuery, bool>> where, QueryOptimizer optimizer)
		{
			if (optimizer == null) throw new Exception("The 'optimizer' parameter cannot be null.");
			SubDomain subDomain = new SubDomain("");

			DataContext dc = new DataContext(ConfigurationValues.GetInstance().ConnectionString);
			Table<CustomerQuery> template = dc.GetTable<CustomerQuery>();
			var cmd = BusinessCollectionPersistableBase.GetCommand<CustomerQuery>(dc, template, where);
			cmd.CommandTimeout = ConfigurationValues.GetInstance().DefaultTimeOut;

			LinqSQLParser parser = LinqSQLParser.Create(cmd.CommandText);
			string sql = "SELECT [t0].[CustomerID] INTO #t\r\n";
			sql += parser.GetFromClause(optimizer) + "\r\n";
			sql += parser.GetWhereClause();
			sql += "\r\n";

			string noLock = "";
			noLock = (optimizer.NoLocking ? "WITH (NOLOCK) " : "");
			sql += "DELETE [Customers] FROM [Customers] " + noLock + "INNER JOIN #t ON [Customers].[CustomerID] = #t.[CustomerID]\r\n";
			sql += ";select @@rowcount";
			cmd.CommandText = sql;
			dc.Connection.Open();
			DateTime startTime = DateTime.Now;
			object p = cmd.ExecuteScalar();
			DateTime endTime = DateTime.Now;
			optimizer.TotalMilliseconds = (long)endTime.Subtract(startTime).TotalMilliseconds;
			dc.Connection.Close();
			return (int)p;
		}

		/// <summary>
		/// Select a paged set of objects from the database
		/// </summary>
		public static CustomerCollection RunSelect(int page, int pageSize, Customer.FieldNameConstants orderByColumn, bool ascending, string filter, out int count)
		{
		  return RunSelect(page, pageSize, orderByColumn.ToString(), ascending, filter, out count, "");
		}

		/// <summary>
		/// Select a paged set of objects from the database
		/// </summary>
		public static CustomerCollection RunSelect(int page, int pageSize, Customer.FieldNameConstants orderByColumn, bool ascending, string filter, out int count, string modifier)
		{
		  return RunSelect(page, pageSize, orderByColumn.ToString(), ascending, filter, out count, modifier);
		}

		/// <summary>
		/// Select a paged set of objects from the database
		/// </summary>
		public static CustomerCollection RunSelect(int page, int pageSize, string orderByColumn, bool ascending, string filter, out int count)
		{
		  return RunSelect(page, pageSize, orderByColumn, ascending, filter, out count, "");
		}

		/// <summary>
		/// Select a paged set of objects from the database
		/// </summary>
		public static CustomerCollection RunSelect(int page, int pageSize, string orderByColumn, bool ascending, string filter, out int count, string modifier)
		{
			try
			{
				int returnCount;
				CustomerCollection returnVal = new CustomerCollection(DomainCustomerCollection.RunSelect(page, pageSize, orderByColumn, ascending, filter, out returnCount, modifier));
				count = returnCount;
				return returnVal;
			}
			catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
			catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
		}

		/// <summary>
		/// Creates an array from the objects in this collection.
		/// </summary>
		/// <returns></returns>
		public Customer[] ToArray()
		{
			return this.ToArray<Customer>();
		}

		/// <summary>
		/// Select a single object from this collection by its primary key.
		/// </summary>
		public static CustomerCollection SelectUsingPK(string customerid)
		{
			return SelectUsingPK(customerid, "");
		}

		/// <summary>
		/// Select a single object from this collection by its primary key.
		/// </summary>
		public static CustomerCollection SelectUsingPK(string customerid, string modifier)
		{
			try
			{
				List<CustomerPrimaryKey> primaryKeys = new List<CustomerPrimaryKey>();
				primaryKeys.Add(new CustomerPrimaryKey(customerid));
				CustomerCollection returnVal = new CustomerCollection(DomainCustomerCollection.SelectByCustomerPks(primaryKeys, modifier));
				return returnVal;
			}
			catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
			catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
		}

		/// <summary>
		/// Select an object list by 'City' field.
		/// <param name="city">The city field</param>
		/// </summary>
		public static CustomerCollection SelectByCity(string city)
		{
			return SelectByCity(city, "");
		}

		/// <summary>
		/// Select an object list by 'City' field.
		/// <param name="city">The city field</param>
		/// <param name="modifier">The identifier used for the create and modify audits.</param>
		/// </summary>
		public static CustomerCollection SelectByCity(string city, string modifier)
		{
			return SelectByCity(city, null, modifier);
		}

		/// <summary>
		/// Select an object list by 'City' field.
		/// <param name="city">The city field</param>
		/// <param name="paging">The paging object to determine how the results are paged.</param>
		/// <param name="modifier">The identifier used for the create and modify audits.</param>
		/// </summary>
		public static CustomerCollection SelectByCity(string city, CustomerPaging paging, string modifier)
		{
			try
			{
			  SubDomain sd = new SubDomain(modifier);
			  CustomerSelectByCity command = new CustomerSelectByCity(city, paging);
			  sd.AddSelectCommand(command);
			  sd.RunSelectCommands();
			  if (paging != null) paging.RecordCount = command.Count;
			  return (CustomerCollection)sd[Collections.CustomerCollection];
			}
			catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
			catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
		}

		/// <summary>
		/// Get an object from this collection by its unique key.
		/// </summary>
		public virtual Customer GetItemByPK(string customerid) 
		{
			try
			{
				lock (wrappedClass.SubDomain)
				{
				if (wrappedClass.GetCustomer(customerid) != null)
				{
					return new Customer(wrappedClass.GetCustomer(customerid));
					}
					else
					{
						return null;
					}
				}
			}
			catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
			catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
		}

		/// <summary>
		/// Returns an enumerator that can be used to iterate through the collection.
		/// </summary>
		/// <returns>An Enumerator that can iterate through the objects in this collection.</returns>
		public virtual System.Collections.IEnumerator GetEnumerator()
		{
			try
			{
				lock (wrappedClass.SubDomain)
				{
					return new CustomerEnumerator(wrappedClass.GetEnumerator());
				}
			}
			catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
			catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
		}

		#region Reject Changes

		/// <summary>
		/// Rejects all the changes for all objects in this collecion, since the last load
		/// </summary>
		/// <returns>void</returns>
		public virtual void RejectChanges()
		{
		  DomainCustomerCollection coll = (DomainCustomerCollection)this.wrappedClass;
		  coll.RejectChanges();
		}

		#endregion

		internal virtual void ResetWrappedClass(DomainCustomerCollection wc)
		{
			wrappedClass = wc;
		}

		#endregion

		#region IPersistableBusinessCollection Explicit Members

		/// <summary>
		/// Returns an item in this collection by index.
		/// </summary>
		/// <param name="index">The zero-based index of the element to get or set. </param>
		/// <returns>The element at the specified index.</returns>
		IPersistableBusinessObject IPersistableBusinessCollection.this[int index]
		{
			get { return this[index]; }
		}

		void IPersistableBusinessCollection.AddItem(IPersistableBusinessObject newItem)
		{
			this.AddItem((Customer)newItem);
		}

		IPersistableBusinessObject IPersistableBusinessCollection.NewItem()
		{
			return this.NewItem();
		}

		#endregion

		#region IBusinessCollection Explicit Members

		/// <summary>
		/// Returns an item in this collection by index.
		/// </summary>
		/// <param name="index">The zero-based index of the element to get or set. </param>
		/// <returns>The element at the specified index.</returns>
		IBusinessObject IBusinessCollection.this[int index]
		{
			get { return this[index]; }
		}

		Enum IBusinessCollection.Collection
		{
			get { return this.Collection; }
		}

		Type IBusinessCollection.ContainedType
		{
			get { return this.ContainedType; }
		}

		SubDomainBase IBusinessCollection.SubDomain
		{
			get { return this.SubDomain; }
		}

		Type ITyped.GetContainedType()
		{
		return typeof(Customer);
		}

		#endregion

		#region GetDatabaseFieldName

		/// <summary>
		/// Returns the actual database name of the specified field.
		/// </summary>
		internal static string GetDatabaseFieldName(Customer.FieldNameConstants field)
		{
			return GetDatabaseFieldName(field.ToString());
		}

		/// <summary>
		/// Returns the actual database name of the specified field.
		/// </summary>
		internal static string GetDatabaseFieldName(string field)
		{
			switch (field)
			{
				case "Address": return "Address";
				case "City": return "City";
				case "CompanyName": return "CompanyName";
				case "ContactName": return "ContactName";
				case "ContactTitle": return "ContactTitle";
				case "Country": return "Country";
				case "CustomerId": return "CustomerID";
				case "Fax": return "Fax";
				case "Phone": return "Phone";
				case "PostalCode": return "PostalCode";
				case "Region": return "Region";
				case "CreatedBy": return "created_by";
				case "CreatedDate": return "created_date";
				case "ModifiedBy": return "modified_by";
				case "ModifiedDate": return "modified_date";
			}
			return "";
		}

		#endregion

		#region IEnumerator

		/// <summary>
		/// An strongly-typed enumerator for the 'Customer' object collection
		/// </summary>
		public class CustomerEnumerator : IEnumerator 
		{
			private IEnumerator internalEnumerator;
			internal CustomerEnumerator(IEnumerator icg)
			{
				internalEnumerator = icg;
			}

			#region IEnumerator Members

			/// <summary>
			/// Reset the enumerator to the first object in this collection
			/// </summary>
			public void Reset()
			{
			try
			{
				internalEnumerator.Reset();
			}
			catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
			catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}

		/// <summary>
		/// Gets the current element in the collection.
		/// </summary>
		/// <returns>The current element in the collection.</returns>
			public object Current
			{
				get
				{
					try
					{
						return new Customer((DomainCustomer)internalEnumerator.Current);
					}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
				}
			}

			/// <summary>
			/// Advances the enumerator to the next element of the collection.
			/// </summary>
			public bool MoveNext()
			{
				try
				{
					bool movedNext = internalEnumerator.MoveNext();
					if(movedNext)
					{
						DomainCustomer currentRow = (DomainCustomer)internalEnumerator.Current;
						while(currentRow.RowState == System.Data.DataRowState.Deleted || currentRow.RowState == System.Data.DataRowState.Detached)
						{
							movedNext = internalEnumerator.MoveNext();
							if(!movedNext)
								break;
							currentRow = (DomainCustomer)internalEnumerator.Current;
						}
					}
					return movedNext;
				}
			catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
			catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}

			#endregion

		}

		#endregion

		#region Search Members

		/// <summary>
		/// Creates a search object to query this collection.
		/// </summary>
		IBusinessObjectSearch IBusinessCollection.CreateSearchObject(SearchType searchType)
		{
			return (IBusinessObjectSearch)this.CreateSearchObject(searchType);
		}

		/// <summary>
		/// Creates a search object to query this collection.
		/// </summary>
		public virtual CustomerSearch CreateSearchObject(SearchType searchType)
		{
			return new CustomerSearch(searchType);
		}

		#endregion

		#region Select By Dates

		/// <summary>
		/// Select objects by their created date.
		/// </summary>
		/// <param name="startDate">The inclusive date on which to start the search.</param>
		/// <param name="endDate">The inclusive date on which to end the search.</param>
		/// <param name="modifier">The identifier used for the create and modify audits.</param>
		public static CustomerCollection SelectByCreatedDateRange(DateTime? startDate, DateTime? endDate, string modifier)
		{
			SubDomain subDomain = new SubDomain(modifier);
			CustomerSelectByCreatedDateRange selectCommand = new CustomerSelectByCreatedDateRange(startDate, endDate);
			subDomain.AddSelectCommand(selectCommand);
			subDomain.RunSelectCommands();
			return subDomain.GetCollection<CustomerCollection>();
		}

		/// <summary>
		/// Select objects by their modified date.
		/// </summary>
		/// <param name="startDate">The inclusive date on which to start the search.</param>
		/// <param name="endDate">The inclusive date on which to end the search.</param>
		/// <param name="modifier">The identifier used for the create and modify audits.</param>
		public static CustomerCollection SelectByModifiedDateRange(DateTime? startDate, DateTime? endDate, string modifier)
		{
			SubDomain subDomain = new SubDomain(modifier);
			CustomerSelectByModifiedDateRange selectCommand = new CustomerSelectByModifiedDateRange(startDate, endDate);
			subDomain.AddSelectCommand(selectCommand);
			subDomain.RunSelectCommands();
			return subDomain.GetCollection<CustomerCollection>();
		}

		#endregion

		#region IEnumerator Members

		object IEnumerator.Current
		{
			get { return this.GetEnumerator().Current; }
		}

		bool IEnumerator.MoveNext()
		{
			return this.GetEnumerator().MoveNext();
		}

		void IEnumerator.Reset()
		{
			this.GetEnumerator().Reset();
		}

		#endregion

		#region IEnumerable<Customer> Members

		IEnumerator<Customer> IEnumerable<Customer>.GetEnumerator()
		{
			List<Customer> retval = new List<Customer>();
			foreach (Customer item in this)
			{
				retval.Add(item);
			}
			return retval.GetEnumerator();
		}

		#endregion

		#region IDisposable Members

		void IDisposable.Dispose()
		{

		}

		#endregion

	}

	#region CustomerSearch

	/// <summary>
	/// The search object for the CustomerCollection.
	/// </summary>
	[Serializable]
	public class CustomerSearch : IBusinessObjectSearch
	{

		private int _maxRowCount = 0;
		private string _address;
		private string _city;
		private string _companyname;
		private string _contactname;
		private string _contacttitle;
		private string _country;
		private string _customerid;
		private string _fax;
		private string _phone;
		private string _postalcode;
		private string _region;
		private SearchType _searchType;

		/// <summary>
		/// Determines the maximum number of rows that are returned. Use 0 for no limit.
		/// </summary>
		public int MaxRowCount
		{
			get { return _maxRowCount; }
			set { _maxRowCount = value; }
		}

		/// <summary>
		/// Determines the maximum number of rows that are returned. Use 0 for no limit.
		/// </summary>
		int IBusinessObjectSearch.MaxRowCount
		{
			get { return this.MaxRowCount; }
			set { this.MaxRowCount = value; }
		}

		/// <summary>
		/// Determines the type of search to be performed.
		/// </summary>
		public SearchType SearchType
		{
			get { return _searchType; }
		}

		/// <summary>
		/// A search object for the 'Customer' collection.
		/// </summary>
		public CustomerSearch(SearchType searchType) 
		{
			_searchType = searchType;
		}

		void IBusinessObjectSearch.SetValue(Enum field, object value)
		{
			this.SetValue((Customer.FieldNameConstants)field, value);
		}

		/// <summary>
		/// Set the specified value on this object.
		/// </summary>
		public void SetValue(Customer.FieldNameConstants field, object value)
		{
			if (field == Customer.FieldNameConstants.Address) this.Address = (string)value;
			if (field == Customer.FieldNameConstants.City) this.City = (string)value;
			if (field == Customer.FieldNameConstants.CompanyName) this.CompanyName = (string)value;
			if (field == Customer.FieldNameConstants.ContactName) this.ContactName = (string)value;
			if (field == Customer.FieldNameConstants.ContactTitle) this.ContactTitle = (string)value;
			if (field == Customer.FieldNameConstants.Country) this.Country = (string)value;
			if (field == Customer.FieldNameConstants.CustomerId) this.CustomerId = (string)value;
			if (field == Customer.FieldNameConstants.Fax) this.Fax = (string)value;
			if (field == Customer.FieldNameConstants.Phone) this.Phone = (string)value;
			if (field == Customer.FieldNameConstants.PostalCode) this.PostalCode = (string)value;
			if (field == Customer.FieldNameConstants.Region) this.Region = (string)value;
		}

		/// <summary>
		/// This field determines the value of the 'Address' field on the 'Customer' object when this search object is applied.
		/// </summary>
		public string Address
		{
			get { return _address; }
			set { _address = value; }
		}

		/// <summary>
		/// This field determines the value of the 'City' field on the 'Customer' object when this search object is applied.
		/// </summary>
		public string City
		{
			get { return _city; }
			set { _city = value; }
		}

		/// <summary>
		/// This field determines the value of the 'CompanyName' field on the 'Customer' object when this search object is applied.
		/// </summary>
		public string CompanyName
		{
			get { return _companyname; }
			set { _companyname = value; }
		}

		/// <summary>
		/// This field determines the value of the 'ContactName' field on the 'Customer' object when this search object is applied.
		/// </summary>
		public string ContactName
		{
			get { return _contactname; }
			set { _contactname = value; }
		}

		/// <summary>
		/// This field determines the value of the 'ContactTitle' field on the 'Customer' object when this search object is applied.
		/// </summary>
		public string ContactTitle
		{
			get { return _contacttitle; }
			set { _contacttitle = value; }
		}

		/// <summary>
		/// This field determines the value of the 'Country' field on the 'Customer' object when this search object is applied.
		/// </summary>
		public string Country
		{
			get { return _country; }
			set { _country = value; }
		}

		/// <summary>
		/// This field determines the value of the 'CustomerId' field on the 'Customer' object when this search object is applied.
		/// </summary>
		public string CustomerId
		{
			get { return _customerid; }
			set { _customerid = value; }
		}

		/// <summary>
		/// This field determines the value of the 'Fax' field on the 'Customer' object when this search object is applied.
		/// </summary>
		public string Fax
		{
			get { return _fax; }
			set { _fax = value; }
		}

		/// <summary>
		/// This field determines the value of the 'Phone' field on the 'Customer' object when this search object is applied.
		/// </summary>
		public string Phone
		{
			get { return _phone; }
			set { _phone = value; }
		}

		/// <summary>
		/// This field determines the value of the 'PostalCode' field on the 'Customer' object when this search object is applied.
		/// </summary>
		public string PostalCode
		{
			get { return _postalcode; }
			set { _postalcode = value; }
		}

		/// <summary>
		/// This field determines the value of the 'Region' field on the 'Customer' object when this search object is applied.
		/// </summary>
		public string Region
		{
			get { return _region; }
			set { _region = value; }
		}

	}

	#endregion 

	#region CustomerPaging

	/// <summary>
	/// A field sort object for the CustomerPaging object.
	/// </summary>
	[Serializable]
	public class CustomerPagingFieldItem : IPagingFieldItem
	{
		/// <summary>
		/// Determines the direction of the sort.
		/// </summary>
		public bool Ascending { get; set; }

		/// <summary>
		/// Determines the field on which to sort.
		/// </summary>
		public ACME.Northwind.Business.Objects.Customer.FieldNameConstants Field { get; set; }

		/// <summary>
		/// Create a sorting field object for the CustomerPaging object.
		/// </summary>
		/// <param name="field">The field on which to sort.</param>
		public CustomerPagingFieldItem(ACME.Northwind.Business.Objects.Customer.FieldNameConstants field)
		{
			this.Field = field;
		}

		/// <summary>
		/// Create a sorting field object for the CustomerPaging object.
		/// </summary>
		/// <param name="field">The field on which to sort.</param>
		/// <param name="ascending">Determines the direction of the sort.</param>
		public CustomerPagingFieldItem(ACME.Northwind.Business.Objects.Customer.FieldNameConstants field, bool ascending)
			: this(field)
		{
			this.Ascending = ascending;
		}

		#region IPagingFieldItem Members

		Enum IPagingFieldItem.GetField()
		{
			return this.Field;
		}

		#endregion

	}

	/// <summary>
	/// The paging object for the Customer collection
	/// </summary>
	[Serializable]
	public class CustomerPaging : IPagingObject
	{
		#region Class Members

		private int _pageIndex = 1;
		private int _recordsperPage = 10;
		private List<CustomerPagingFieldItem> _orderByList = new List<CustomerPagingFieldItem>();		
		private int _recordCount = 0;

		#endregion

		#region Constructors

		/// <summary>
		/// Creates a paging object
		/// </summary>
		public CustomerPaging()
			: this(1, 10, null)
		{
		}

		/// <summary>
		/// Creates a paging object
		/// </summary>
		/// <param name="pageIndex">The page number to load</param>
		/// <param name="recordsperPage">The number of records per page.</param>
		public CustomerPaging(int pageIndex, int recordsperPage)
			: this(pageIndex, recordsperPage, null)
		{
		}

		/// <summary>
		/// Creates a paging object
		/// </summary>
		/// <param name="pageIndex">The page number to load</param>
		/// <param name="recordsperPage">The number of records per page.</param>
		/// <param name="field">The field on which to sort.</param>
		/// <param name="ascending">Determines the sorted direction.</param>
		public CustomerPaging(int pageIndex, int recordsperPage, ACME.Northwind.Business.Objects.Customer.FieldNameConstants field, bool ascending)
			: this(pageIndex, recordsperPage, new CustomerPagingFieldItem(field, ascending))
		{
		}

		/// <summary>
		/// Creates a paging object
		/// </summary>
		/// <param name="pageIndex">The page number to load</param>
		/// <param name="recordsperPage">The number of items per page.</param>
		/// <param name="orderByField">The field on which to sort.</param>
		public CustomerPaging(int pageIndex, int recordsperPage, CustomerPagingFieldItem orderByField)
		{
			if (pageIndex < 1) throw new Exception("The PageIndex must be 1 or greater.");
			if (recordsperPage < 1) throw new Exception("The RecordsPerPage must be 1 or greater.");

			_pageIndex = pageIndex;
			_recordsperPage = recordsperPage;
			if (orderByField != null)
				_orderByList.Add(orderByField);
		}

		#endregion

		#region Property Implementations

		/// <summary>
		/// The page number of load.
		/// </summary>
		public int PageIndex
		{
			get { return _pageIndex; }
			set
			{
				if (value < 1) throw new Exception("The PageIndex must be 1 or greater.");
				_pageIndex = value;
			}
		}

		/// <summary>
		/// The number of items per page.
		/// </summary>
		public int RecordsperPage
		{
			get { return _recordsperPage; }
			set
			{
				if (value < 1) throw new Exception("The RecordsperPage must be 1 or greater.");
				_recordsperPage = value;
			}
		}

		/// <summary>
		/// A list of fields on which to sort.
		/// </summary>
		public List<CustomerPagingFieldItem> OrderByList
		{
			get { return _orderByList; }			
		}

		/// <summary>
		/// The total number of non-paged items returned for the search.
		/// </summary>
		public int RecordCount
		{
			get { return _recordCount; }
			set { _recordCount = value; }
		}

		#endregion

		#region IPagingObject Members

		IEnumerable<IPagingFieldItem> IPagingObject.GetOrderByList()
		{
			List<IPagingFieldItem> retval = new List<IPagingFieldItem>();
			foreach (IPagingFieldItem item in this.OrderByList)
			{
				retval.Add(item);
			}
			return retval.AsEnumerable();
		}

		#endregion

	}

	#endregion

}
